Искусство схемотехники. Том 2 [Изд.4-е] - Пауль Хоровиц
Шрифт:
Интервал:
Закладка:
hexf = a & !b & !c & !d & e & f & g;
/** Logic Equations **/
D3 = eight # nine # hexa # hexb # hexc # hexd # hexe # hexf;
D2 = four # five # six # seven # hexc # hexd # hexe # hexf;
D1 = two # three # six # seven # hexa # hexb # hexe # hexf;
D0 = one # three # five # seven # nine # hexb # hexd # hexf
Рис. 8.77. Спецификация преобразователя 7-сегментного представления в 16-ричное на языке CUPL.
Окончательно каждый двоичный выходной бит записывается как сумма (ИЛИ) цифровых переменных, при которых этот бит устанавливается. Мы используем уровни отрицательной логики, потому что 16L8 представляет матрицу И-ИЛИ-НЕ. Этим заканчивается логическая спецификация для языка.
Упражнение 8.29. Проверьте для себя правильность нашей работы, записав некоторые из отображаемых символов, через заданные нами промежуточные переменные zero-next.
Язык CUPL сначала использует определение промежуточных переменных для записи выражений D0-D3 прямо в термах входных переменных a — f, работа, которая подобно ассемблеру PALASM должна исполняться нами изначально. В этом случае логические уравнения представлены в желательной И-ИЛИ-НЕ форме. Однако мы не закончили на этом, так как 16L8 (и все другие комбинационные ПМЛ) допускают не более 7 термов произведений для каждой суммы, тогда как мы имеем 9, 8, 9 и 10 соответственно для выходов D0-D3. Одним решением может быть связывание выхода через вторичный вентиль ИЛИ, для того чтобы получить желательное число термов произведений в сумме.
Эта обычно рассматриваемая форма плоха, так как она удваивает задержки распространения, хотя это не так важно в медленных устройствах, подобных этому. Лучшее решение — произвести логическую минимизацию, используя логическую эквивалентность по формуле Моргана, например.
Мы запускаем минимизатор CUPL, который выдает термы произведений (рис. 8.78).
** Expanded Product Terms **
D0 =>
a & b & c & d & !e & g
# a & b & с & !e & f & g
# a & с & d & !e & f & g
# b & с & !d & !e & !f & !g
# !a & !b & c & d & e & f & g
# a & !b & !c & !d & e & f & g
# !a & b & c & d & e & !f & g
D1 =>
a& !b & !c & e & f & g
# !b & c & d & e & f &g
# a & b & с & !d & e & f & g
# a & b & !c & d & e & !f & g
# a & b & c & d & !e & !f & g
# a & b & с & !d & !e & !f & !g
D2 =>
а & !b & !с & d & е & f
# а & !b & c & d & f & g
# а & !b & !с & е & f & g
# !а & b & с & !d & !е & f & g
# !a & b & c & d & e & !f & g
# !a & !b & !c & d & e & !f & g
# a & b & с & !d & !e & !f & !g
D3 =>
a & b & c & f & g
# a & !b & !c & d & e & f
# a & !b & !c & e & f & g
# !a & !b & c & d & e & f & g
# !a & b & c & d & e & !f & g
# !a & !b & !c & d & e & !f & g
D0.oe => 1
D1.oe => 1
D2.oe => 1
D3.oe => 1
Рис. 8.78. Преобразователь 7-сегментного представления в 16-ричное с минимизированными термами произведения.
Взгляните, все удовлетворяет ограничению «7 произведений». CUPL также рисует для вас карту перемычек (рис. 8.79).
Рис. 8.79. Карта перемычек преобразователя 7-сегментного представления в 16-ричное.
Конечно, вы не программируете ПМЛ так, а используете вместо этого прямую загрузку универсального JEDEC программирующего формата. В этом примере язык CUPL, очевидно, делает трудную задачу простой.
Пример использования языка CUPL для программирования автомата-продавца (последовательная схема). Произвольная машина состояний (разд. 8.18) имеет набор состояний и правил перехода для движения между этими состояниями по каждому фронту синхроимпульса. Правила перехода зависят от текущего состояния и от частной комбинации входных уровней, существующих на следующем фронте. Вы можете соорудить машину состояний на программируемой логике, содержащей регистры, если а) существует достаточное число битов в регистре для представления всех возможных состояний (например, с 4-разрядным регистром вы можете иметь до 16 состояний), и б) существует достаточное число входов и логических вентилей для реализации правил перехода.
Как пример, давайте спроектируем регистровую ПМЛ для диаграммы состояний на рис. 8.80.
Рис. 8.80. Диаграмма состояний торгового автомата.
Это — торговый автомат, предназначенный для выдачи бутылки сладкой шипучей жидкости, когда опущено 25 цент или более. Существует некоторый вид монетного интерфейса, который «заглатывает», распознает монету и посылает на наш ПМЛ 2-битовый входной сигнал (С1, С0), действительный для одного такта, показывающего монету, которую опустили (01-5 цент, 10–10 — цент монета, 11–25 — цент монета, 00 — нет монеты). Задача машины состояний добавлять к общему вкладу и формировать выход, называемый «бутылка», когда опущено достаточно монет. Рис. 8.81 показывает спецификацию, выполненную в синтаксисе машины состояний языка CUPL.
/** Inputs **/
Pin = elk; /* clock — positive edge */
Pin = c0; /* coin type — low bit */
Pin = c1; /* coin type — high bit */
Pin = reset; /* reset input */
/** Outputs **/
Pin 18 = !Q0; /* bit 0 of state variable */
Pin 17 = !Q1; /* bit 1 */
Pin 16 = !Q2; /* bit 2 */
Pin 15 = !bottle; /* bottle disgorge command */
/* Define machine states with symbolic names;
"enough" = 25 cents or more */
$define S0 'b'000
$define S5 'b'001
$define S10 'b'010
$define S15 'b'011
$define S20 'b'100
$define ENOUGH 'b'101
/* define intermediate variables */
nocoin = !c0 & !c1 & !reset;
nicke1 = c0 & !c1 & !reset;
dime = !c0 & c1 & !reset;
quarter = c0 & c1 & !reset;
/* Define state bit variable field */
field statebit = [Q2..0];
/* Transition rules for vending machine */
sequence statebit {
present S0 if nocoin next S0;
if nicke1 next S5;
if dime next S10;
if quarter next ENOUGH out bottle;
present S5 if nocoin next S5
if nicke1 next S10;
if dime next S15;
if quarter next ENOUGH out bottle;
present S10 if nocoin next S10
if nicke1 next S15;
if dime next S20;
if quarter next ENOUGH out bottle;
present S15 if nocoin next S15
if nicke1 next S20;
if dime next ENOUGH out bottle;
if quarter next ENOUGH out bottle;
present S20 if nocoin next S20
if nicke1 next ENOUGH out bottle;
if dime next ENOUGH out bottle;
if quarter next ENOUGH out bottle;
present ENOUGH next S0; }
Рис. 8.81. Спецификация торгового автомата на языке CUPL.
Как и прежде, мы начнем с определения входных-выходных контактов. Заметим, что мы добавили вход reset (сброс) так, чтобы вы могли перейти к начальному состоянию S0 (нет монеты). Затем мы определим состояния, потом правила перехода между ними. Если какие-либо выходы, либо регистровые, либо комбинационные, необходимо генерировать в течение состояний или переходов между состояниями, они определяются в то же самое время. В этом примере выход «бутылка» специфицируется как раздельный выходной регистр, т. е. выходные состояния дешифрировать не нужно. Фактически нужен только выход, а биты Q0-2 машины состояний могут быть представлены во внутренних регистрах, которые не генерируют прямо выводы; некоторые программируемые логические устройства имеют также внутренние регистры в дополнение к обычным выходным регистрам.
Заметим, что вы должны определить точно переход из некоторого состояния в себя, также, как мы делали для входа «нет монеты». Неопределенное условие безусловно сбрасывает состояние во все нули. Это происходит потому, что эти условия собираются в комбинационную логику для выставления на D-входы регистров и, таким образом, если условие не удовлетворяется, то соответствующий D-вход не подтверждается. Рис. 8.82 показывает вывод из языка CUPL.
** Expanded Product Terms **
Q0.d =>
!Q0 & !Q1 & cQ & !reset
# !Q0 & !Q2 & cO & !reset
# Q0 & !Q2 & !c0 & !reset
# Q0 & !Q2 & c1 & !reset
# !Q0 & !Q1 & Q2 & c1 & !reset
Q1.d =>
!Q1 & !Q2 & !c0 & c1 & !reset
# !Q0 & Q1 & !Q2 & !c1 & !reset
# Q1 & !Q2 & !c0 & !c1 & !reset
# Q0 & !Q1 & !Q2 & cO & !c1 & !reset
Q2.d =>
!Q0 & !Q1 & Q2 & !reset
# Q1 & !Q2 & c1 & !reset
# !Q2 & c0 & c1 & !reset
# Q0 & Q1 & !Q2 & c0 & !reset
bottle.d =>
!Q2 & c0 & c1 & !reset
# !Q0 & !Q1 & Q2 & c0 & !reset
# !Q0 & !Q1 & Q2 & c1 & !reset
# Q0 & Q1 &!Q2 & c1 & !reset
statebit =>
Q2, Q1, Q0
Рис. 8.82. Выход CUPL для торгового автомата.
Ничего очевидного или простого в логике, поскольку и состояние автомата (S0-S5) и входящие переменные (С0-1) определены в виде двоичных чисел, а логика работает по отдельным битам. Таким образом, результирующая логика не сильно связана с первоначальным описанием состояний (рис. 8.81). Фактически, конкретный выбор состояний (возрастающий двоичный код 0–5) мог бы быть различным, это полностью изменило бы результирующую логику. В этом случае этот пример легко укладывается в ограничениях ПМЛ 16R6 (8 термов произведений на регистр): если это не так, мы могли бы попытаться переопределить состояния, что часто приводит к более простой логической реализации. Заметим, что вход сброса действует, заменяя безусловность всех D-входов, которую мы задали посредством нашего задания промежуточных переменных «нет монеты», «5 цент» и т. д.